package com.yunxin.download.server.infra.support.mgb;

import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.MergeConstants;
import org.mybatis.generator.internal.util.StringUtility;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import java.util.Set;

/**
 * @author zero°
 * @since 2023-05-24
 */
public class ExtendCommentGenerator implements CommentGenerator {

    private final Properties properties;

    public ExtendCommentGenerator() {
        properties = new Properties();
    }

    @Override
    public void addConfigurationProperties(Properties properties) {
        // 获取自定义的 properties
        this.properties.putAll(properties);
    }

    /**
     * 模型类注释
     * @param topLevelClass topLevelClass
     * @param introspectedTable introspectedTable
     */
    @Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        addClassJavaDoc(topLevelClass, introspectedTable);
    }

    /**
     * 模型字段注释
     * @param field field
     * @param introspectedTable introspectedTable
     * @param introspectedColumn introspectedColumn
     */
    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        if (StringUtility.stringHasValue(introspectedColumn.getRemarks())) {
            field.addJavaDocLine("/**");
            field.addJavaDocLine(" * " + introspectedColumn.getRemarks());
            field.addJavaDocLine(" */");
        }
    }

    /**
     * 添加java类注解
     * @param innerClass innerClass
     * @param introspectedTable introspectedTable
     */
    private void addClassJavaDoc(InnerClass innerClass, IntrospectedTable introspectedTable){
        String author = properties.getProperty("author", "Your name");
        String dateFormat = properties.getProperty("dateFormat", "yyyy-MM-dd");
        SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat);
        // 获取表注释
        if (StringUtility.stringHasValue(introspectedTable.getRemarks())) {
            innerClass.addJavaDocLine("/**");
            innerClass.addJavaDocLine(" * " + introspectedTable.getRemarks());
            innerClass.addJavaDocLine(" *");
            innerClass.addJavaDocLine(" * @author " + author);
            innerClass.addJavaDocLine(" * @since   " + dateFormatter.format(new Date()));
            innerClass.addJavaDocLine(" */");
        } else {
            innerClass.addJavaDocLine("/**");
            innerClass.addJavaDocLine(" * @author " + author);
            innerClass.addJavaDocLine(" * @since   " + dateFormatter.format(new Date()));
            innerClass.addJavaDocLine(" */");
        }
    }

    /**
     * Java类的类注释
     * @param innerClass innerClass
     * @param introspectedTable introspectedTable
     */
    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
        addClassJavaDoc(innerClass, introspectedTable);
    }

    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean b) {
        addClassJavaDoc(innerClass, introspectedTable);
    }

    @Override
    public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {

    }

    @Override
    public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {

    }

    @Override
    public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {

    }

    /**
     * 普通方法的注释，这里主要是XXXMapper.java里面的接口方法的注释
     * @param method method
     * @param introspectedTable introspectedTable
     */
    @Override
    public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
        method.addJavaDocLine("/**");
        addMethodJavadoc(method);
        method.addJavaDocLine(" */");

    }

    @Override
    public void addJavaFileComment(CompilationUnit compilationUnit) {
    }

    @Override
    public void addComment(XmlElement xmlElement) {

    }

    @Override
    public void addRootComment(XmlElement xmlElement) {

    }

    @Override
    public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) {

    }

    @Override
    public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> set) {

    }

    @Override
    public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) {

    }

    @Override
    public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> set) {

    }

    @Override
    public void addClassAnnotation(InnerClass innerClass, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) {

    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable) {

    }

    /**
     * 添加方法注释
     * @param javaElement javaElement
     */
    protected void addMethodJavadoc(JavaElement javaElement) {
        javaElement.addJavaDocLine(" *");
        String sb = " * " + MergeConstants.NEW_ELEMENT_TAG;
        javaElement.addJavaDocLine(sb);
    }

}
